home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / ver / 050 / ippon050.lzh / eshot.c < prev    next >
C/C++ Source or Header  |  2000-07-07  |  4KB  |  172 lines

  1. /* eshot.c */
  2.  
  3. #include <stdio.h>
  4. #include <xsp2lib.h>
  5.  
  6. #include "main.h"
  7. #include "player.h"
  8. #include "eshot.h"
  9.  
  10. #define    PALET_ESHOT    0x0300
  11.  
  12. #define ESHOT_MAX    200    /* 敵弾最大数 */
  13. static ESHOT eshot[ESHOT_MAX];    /* ワーク */
  14.  
  15.  
  16.  
  17. /* ゲーム開始時に呼ばれる */
  18. void EshotInit (void)
  19. {
  20.     int i;
  21.  
  22.     /* リストをつなげる */
  23.     eshot_top = NULL;
  24.     eshot_null_top = eshot;
  25.     for (i = 0; i < ESHOT_MAX; i++)
  26.         eshot[i].next = &eshot[i + 1];
  27.  
  28.     eshot[ESHOT_MAX - 1].next = NULL;
  29. }
  30.  
  31.  
  32.  
  33. /* 敵弾出現時に呼ばれる */
  34. void EshotAlloc (short type, signed short x, signed short y, unsigned char speed, unsigned char angle, signed short t)
  35. {
  36.     ESHOT *p;
  37.  
  38.     if (eshot_null_top == NULL)    /* ワークの空きはあるか? */
  39.         return;
  40.  
  41.     p = eshot_null_top;
  42.     eshot_null_top = p->next;
  43.     p->next = eshot_top;
  44.     eshot_top = p;
  45.  
  46.     p->lx = (x - 8) << 16;    /* (8,8) がスプライト座標の中心なので補正 */
  47.     p->ly = (y - 8) << 16;
  48.     p->vx = xytable[speed][angle].x;
  49.     p->vy = xytable[speed][angle].y;
  50.     if (t) {        /* t フレーム後の値を初期値に */
  51.         p->lx += (p->vx * t);
  52.         p->ly += (p->vy * t);
  53.     }
  54.     /* メモ:敵弾の速度と当り判定の大きさについて */
  55.     /* eshot->hx が以下の場合、eshot->vx の最大値は以下の通り */
  56.     /* (hx,vx 未満) = (2,1.0),(3,3.0),(4,5.0),(5,7.0),(6,9.0) */
  57.     /* 算出式は以下の通り */
  58.     /* eshot->vx+player->vx > 2*eshot->hx の時判定抜けが発生 */
  59.     /* player->vx の最大値は 3.0(高速移動時) */
  60.  
  61.     switch (p->type = type) {
  62.     case ESHOT_NRG01:    /* エネルギー弾(極小) */
  63.         p->hit_p = 2;    /* 速度を 1.0 未満にする事 */
  64.         p->pt = sp_eshot + type;
  65.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  66.         break;
  67.  
  68.     case ESHOT_NRG02:    /*    〃   (小) */
  69.     case ESHOT_NRG03:    /*    〃   (中) */
  70.     case ESHOT_NRG04:    /*    〃   (大) */
  71.         p->hit_p = 3;    /* 速度を 3.0 未満にする事 */
  72.         p->pt = sp_eshot + type;
  73.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  74.         break;
  75.  
  76.     case ESHOT_NRG05:    /*    〃   (特大) */
  77.     case ESHOT_NRG06:    /*    〃   (特大) */
  78.     case ESHOT_NRG22:    /*    〃   (小横に2個) */
  79.     case ESHOT_NRG32:    /*    〃   (中横に2個) */
  80.     case ESHOT_NRG23:    /*    〃   (小3角形に3個) */
  81.     case ESHOT_NRG24:    /*    〃   (小正方形に4個) */
  82.     case ESHOT_NRG14N:    /*    〃   (小斜めに4個) */
  83.     case ESHOT_NRG24N:    /*    〃   (中斜めに4個) */
  84.     case ESHOT_NRG34N:    /*    〃   (中斜めに4個) */
  85.     case ESHOT_NRG34:    /*    〃   (中正方形に4個) */
  86.     case ESHOT_NRG15:    /*    〃   (小5個) */
  87.     case ESHOT_NRG35:    /*    〃   (小と大正方形に5個) */
  88.         p->hit_p = 4;    /* 速度を 5.0 未満にする事 */
  89.         p->pt = sp_eshot + type;
  90.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  91.         break;
  92. #if    0
  93.     case ESHOT_LASER01:
  94.         p->hit_p = 3;    /* 速度を 3.0 未満にする事 */
  95.         p->pt = sp_laser + 8;
  96.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  97.         break;
  98.  
  99.     case ESHOT_LASEREX:
  100.         p->hit_p = 4;    /* 速度を 5.0 未満にする事 */
  101.         p->pt = sp_laser + 9;
  102.         p->info = PALET_ESHOT | PRIORITY_ESHOT;
  103.         break;
  104. #endif
  105.     default:
  106.         break;
  107.     }
  108.  
  109. }
  110.  
  111.  
  112.  
  113. /* 垂直同期ごとに呼ばれる */
  114. void EshotMove (void)
  115. {
  116.     ESHOT *p, *q;
  117.     signed short pl_x = player->x - 8, pl_y = player->y - 8;
  118.  
  119. #ifdef DEBUG
  120.     eshot_sum = 0;
  121. #endif
  122.     p = eshot_top;        /* 現在注目しているワーク */
  123.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  124.  
  125.     while (p != NULL) {
  126.         signed short p_x, p_y;
  127.  
  128. #ifdef DEBUG
  129.         eshot_sum++;
  130. #endif
  131.         /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  132.         p_x = p->x = (p->lx += p->vx) >> 16;
  133.         p_y = p->y = (p->ly += p->vy) >> 16;
  134.  
  135.         /* 敵弾が画面外に出たか? */
  136.         /* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
  137.         if (((unsigned short) p_x > 256 + 16) || ((unsigned short) p_y > 256 + 16)) {
  138.             /* 敵弾が画面外へ出たので消去 */
  139.             if (q == NULL) {    /* リストの一番最初を削除 */
  140.                 eshot_top = p->next;
  141.                 p->next = eshot_null_top;
  142.                 eshot_null_top = p;
  143.                 q = NULL;
  144.                 p = eshot_top;
  145.             } else {
  146.                 q->next = p->next;
  147.                 p->next = eshot_null_top;
  148.                 eshot_null_top = p;
  149.                 p = q->next;
  150.             }
  151.         } else {
  152.             /* 画面外へ出ていない時 */
  153.  
  154.             /* 敵弾と自機の当たり判定 */
  155.             /* この辺の最適化は -fstrings-reduce が頑張ってくれるハズ */
  156.             signed short t, t2 = p->hit_p;
  157.             if (((t = p_y - t2) <= pl_y)
  158.                 && ((t += (short) (t2 << 1)) >= pl_y)
  159.                 && ((t = p_x + t2) >= pl_x)
  160.                 && ((t -= (short) (t2 << 1)) <= pl_x)) {
  161.                 if ((player->status == PLAYER_STATUS_ALIVE) && (player->muteki == 0))
  162.                     player->status = PLAYER_STATUS_DEAD;
  163.             } else {
  164.                 xsp_set_st (p);
  165.             }
  166.  
  167.             q = p;
  168.             p = p->next;
  169.         }
  170.     }
  171. }
  172.